package com.hgy.fxui.controller;

import com.hgy.fxui.dao.DrugDao;
import com.hgy.fxui.dao.PurchaseOrderDao;
import com.hgy.fxui.dao.SupplierDao;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.chart.*;
import javafx.scene.layout.GridPane;
import javafx.collections.FXCollections;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.time.LocalDateTime;
import java.time.Month;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@Controller
public class DashboardController {
    @FXML
    private PieChart supplierChart;
    
    @FXML
    private PieChart drugCategoryChart;
    
    @FXML
    private BarChart<String, Number> inventoryChart;
    
    @FXML
    private LineChart<String, Number> purchaseChart;

    @FXML
    private GridPane root;

    private DrugDao drugDao;
    
    private SupplierDao supplierDao;
    
    private PurchaseOrderDao purchaseOrderDao;
    
    private ScheduledExecutorService scheduler;
    
    private boolean isUISetupCompleted = false;

    public DashboardController() {
        this.scheduler = Executors.newSingleThreadScheduledExecutor();
        log.debug("DashboardController 实例已创建");
    }

    public void setDrugDao(DrugDao drugDao) {
        this.drugDao = drugDao;
    }

    public void setSupplierDao(SupplierDao supplierDao) {
        this.supplierDao = supplierDao;
    }

    public void setPurchaseOrderDao(PurchaseOrderDao purchaseOrderDao) {
        this.purchaseOrderDao = purchaseOrderDao;
    }

    @FXML
    public void initialize() {
        log.info("仪表盘基础UI初始化开始...");
        if (!isUISetupCompleted) {
            root.getStyleClass().add("dashboard");
            isUISetupCompleted = true;
        }
        log.info("仪表盘基础UI初始化完成");
    }

    public void fullInitialize() {
        log.info("开始仪表盘完整初始化...");

        // 验证依赖
        if (drugDao == null || supplierDao == null || purchaseOrderDao == null) {
            throw new IllegalStateException("DAO 未完全初始化!");
        }

        // 确保基础UI设置已完成
        if (!isUISetupCompleted) {
            initialize();
        }

        // 初始加载数据
        updateCharts();
        
        // 设置定时更新（每30秒刷新一次）
        scheduler.scheduleAtFixedRate(this::updateCharts, 30, 30, TimeUnit.SECONDS);

        log.info("仪表盘完整初始化完成");
    }

    private void updateCharts() {
        try {
            Platform.runLater(() -> {
                updateSupplierChart();
                updateDrugCategoryChart();
                updateInventoryChart();
                updatePurchaseChart();
            });
        } catch (Exception e) {
            log.error("更新图表数据失败", e);
        }
    }

    private void updateSupplierChart() {
        try {
            // 获取供应商地区分布数据
            List<Map<String, Object>> supplierData = supplierDao.getSupplierRegionDistribution();
            supplierChart.setData(FXCollections.observableArrayList(
                supplierData.stream()
                    .map(data -> new PieChart.Data(
                        (String) data.get("region"),
                        ((Number) data.get("count")).doubleValue()
                    ))
                    .toList()
            ));
            supplierChart.setTitle("供应商地区分布");
        } catch (Exception e) {
            log.error("更新供应商分布图表失败", e);
        }
    }

    private void updateDrugCategoryChart() {
        try {
            // 获取药品分类统计
            List<Map<String, Object>> categoryData = drugDao.getDrugCategoryDistribution();
            drugCategoryChart.setData(FXCollections.observableArrayList(
                categoryData.stream()
                    .map(data -> new PieChart.Data(
                        (String) data.get("category"),
                        ((Number) data.get("count")).doubleValue()
                    ))
                    .toList()
            ));
            drugCategoryChart.setTitle("药品分类分布");
        } catch (Exception e) {
            log.error("更新药品分类图表失败", e);
        }
    }

    private void updateInventoryChart() {
        try {
            // 获取库存量TOP 10的药品
            List<Map<String, Object>> stockData = drugDao.getTopDrugsByStock(10);
            
            XYChart.Series<String, Number> series = new XYChart.Series<>();
            series.setName("库存数量");
            
            stockData.forEach(data -> 
                series.getData().add(new XYChart.Data<>(
                    (String) data.get("name"),
                    (Number) data.get("stock")
                ))
            );
            
            inventoryChart.getData().clear();
            inventoryChart.getData().add(series);
            inventoryChart.setTitle("药品库存TOP 10");
        } catch (Exception e) {
            log.error("更新库存图表失败", e);
        }
    }

    private void updatePurchaseChart() {
        try {
            // 获取近6个月的采购金额统计
            List<Map<String, Object>> purchaseData = purchaseOrderDao.getMonthlyPurchaseAmount(6);
            
            XYChart.Series<String, Number> series = new XYChart.Series<>();
            series.setName("采购金额");
            
            purchaseData.forEach(data -> 
                series.getData().add(new XYChart.Data<>(
                    (String) data.get("month"),
                    (Number) data.get("amount")
                ))
            );
            
            purchaseChart.getData().clear();
            purchaseChart.getData().add(series);
            purchaseChart.setTitle("近6个月采购金额趋势");
        } catch (Exception e) {
            log.error("更新采购趋势图表失败", e);
        }
    }

    public void cleanup() {
        if (scheduler != null && !scheduler.isShutdown()) {
            try {
                scheduler.shutdown();
                if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                    scheduler.shutdownNow();
                }
            } catch (InterruptedException e) {
                scheduler.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }
}
